﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;


namespace Pibby.Core.Tests
{
	[TestClass]
	public class IntegrationTestBase
	{
		private static readonly object lockObject = new object();

		[TestInitialize]
		public void Setup()
		{
			System.Threading.Monitor.Enter(lockObject);

			try
			{
				// setup app...
				System.Threading.Thread.Sleep(1000);
			}
			catch
			{
				System.Threading.Monitor.Exit(lockObject);

				throw;
			}
		}

		[TestCleanup]
		public void TearDown()
		{
			try
			{
				System.Threading.Thread.Sleep(1000);
			}
			finally
			{
				System.Threading.Monitor.Exit(lockObject);
			}
		}
	}

	[TestClass]
	public class ContractTests : IntegrationTestBase
	{
		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_EnsureThatFalse_ThrowsException()
		{
			Contract.EnsureThat(false);

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_EnsureThatFalse_ThrowsExceptionWithMessage()
		{
			Contract.EnsureThat(false, "This is the message you should see");

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_NullRef_ThrowsException()
		{
			Contract.EnsureIsNotNull(null);

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_NullObject_ThrowsException()
		{
			object o = null;
			Contract.EnsureIsNotNull(o, "Object should not be null");

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_NullString_ThrowsException()
		{
			string notInitialised = null;
			Contract.EnsureIsNotNullOrEmpty(notInitialised);

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		[ExpectedException(typeof(ContractFailureException))]
		public void Contract_EmptyString_ThrowsException()
		{
			string test = string.Empty;
			Contract.EnsureIsNotNullOrEmpty(test, "string should not be empty");

			Assert.Fail("Expecting a contract violation exception to fire");
		}

		[TestMethod]
		public void Contract_ValidCondition_DoesNotThrowException()
		{
			Contract.EnsureThat(true);
		}
	}
}
